package com.know.email;

import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.Executor;
import java.util.concurrent.Executors;
import java.util.concurrent.LinkedBlockingQueue;

import javax.mail.Authenticator;
import javax.mail.BodyPart;
import javax.mail.Message.RecipientType;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;


/**
 * 发送邮件的多线程
 * @author octopus
 *
 */
//<dependency>
//<groupId>javax.mail</groupId>
//<artifactId>mail</artifactId>
//<version>1.4</version>
//</dependency>
public class MailThreadService extends Thread{
	private static final Logger LOGGER =LoggerFactory.getLogger(MailThreadService.class);
	private static MailThreadService instance = new MailThreadService();
    //private static final  String SENDCLOUD_SMTP_HOST = "smtpcloud.sohu.com";
	///邮箱服务商
    private static final  String SENDCLOUD_SMTP_HOST = "smtp.126.com";
    //邮件端口号
    private static final  int SENDCLOUD_SMTP_PORT = 25;
    public static final  String customPhone = "400-9696-906";
	private static final String contentActivate = "<p>亲爱的%s：</p><p>&nbsp; &nbsp; 请激活您的开薪工资账户，如果点击无效，请复制下方网页地址到浏览器地址栏中打开：<a href='%s' target='_blank'>%s</a></p>";
	private static final String contentActivateSuccess = "<p>[开薪工资］尊敬的用户，您的开薪工资账户已经激活。</p><p>请登录<a href='%s'>%s</a>查看您的开薪工资账户。</p>";
	private static final String contentFreeze = "<p>[开薪工资］尊敬的用户，由于密码输入错误次数已达当日上限，您的账户已经被冻结。将于当日24:00解冻，请您耐心等候。给您造成不便，请原谅。</p>";
	private static final String contentModifyLoginPass = "<p>［开薪工资］您的账户于%s修改登录密码成功，如非本人操作，请联系客服电话：%s。</p>";
	private static final String contentModifyPayPass = "<p>［开薪工资］您的账户于%s修改支付密码成功，如非本人操作，请联系客服电话：%s。</p>";
	private static final String contentReset = "<p>［开薪工资］您的账户已经重置成功，请登录<a href='%s' target='_blank'>%s</a>激活您的账户。</p>";
	private static final String contentModifyPhone = "<p>［开薪工资］您绑定的手机号码%s成功修改为%s，所有操作将使用新的号码。</p>";
	private static final String contentModifyEmail = "<p>您绑定的邮箱%s成功修改为%s，所有操作将使用新的邮箱。</p>";
	private static final String contentModifyBank = "<p>［开薪工资］您绑定的银行卡，%s成功修改为%s，所有操作将使用新的银行卡。</p>";
	private static final String contentModifyCard = "<p>［开薪工资］您绑定身份ID，%s成功修改为%s，所有操作将使用新身份ID。</p>";
	private static final String contentConfirm = "<p>[开薪工资］亲爱的%s</p><p>&nbsp; &nbsp; 请确认您的开薪工资账户信息</p><p>如果点击无效，请复制下方网页地址到浏览器地址栏中打开:</p><p><a href='%s' target='_blank'>%s</a>查看您的开薪工资账户。</p>";
	private static final String contentRemind = "<p>］尊敬的用户，您的开薪工资账户信息已修改成功。请登录<a href='%s' target='_blank'>%s</a>查看您的开薪工资账户</p>";	
    private static Session mailSession;
    private static Transport transport;
	private Executor executor = Executors.newSingleThreadExecutor();

	private LinkedBlockingQueue<Runnable> tasks = new LinkedBlockingQueue<>();

	static{
		try {
			// 配置javamail
			Properties props = System.getProperties();
			props.setProperty("mail.transport.protocol", "smtp");
			props.put("mail.smtp.host", SENDCLOUD_SMTP_HOST);
			props.put("mail.smtp.port", SENDCLOUD_SMTP_PORT);
			props.setProperty("mail.smtp.auth", "true");
			props.put("mail.smtp.connectiontimeout", 10000); // 单位：毫秒
			props.put("mail.smtp.timeout", 10000); // 单位：毫秒

			props.setProperty("mail.mime.encodefilename", "true");

			// 使用api_user和api_key进行验证
			final String apiUser = "zhanlong1988@126.com";
			final String apiKey = "wangyi147";

			mailSession = Session.getInstance(props, new Authenticator() {
				@Override
				protected PasswordAuthentication getPasswordAuthentication() {
					return new PasswordAuthentication(apiUser, apiKey);
				}
			});
		} catch (Exception e) {
			LOGGER.error("init email service error.", e);
		}
	}


	 /* 私有构造方法，防止被实例化 */  
	private MailThreadService(){this.start();}
	//获取配置文件，初始化sender；
	public static MailThreadService getInstance(){
		return instance;
	}

	public void run(){
		LOGGER.info("start sms service ");
		Runnable r;
		try {
			while((r = tasks.take()) != null){
				executor.execute(r);
			}
		} catch (InterruptedException e) {
			LOGGER.error("InterruptedException in sms service",e);
		}
	}
	
	/**
	 * 简单下发
	 * @param to
	 * @param content
	 * @return
	 * @throws MessagingException
	 * @throws UnsupportedEncodingException
	 */
	private void sendEmail(String to,String subject,String content) {
		SendEmailThread sendEmailThread = new SendEmailThread(to, subject, content);
		try {
			tasks.put(sendEmailThread);
		} catch (InterruptedException e) {
			LOGGER.error("send email service add task error.", e);
		}
	}
	
	
	
	/**
	 * 简单下发可以指定多个用户
	 * @param toList
	 * @param subject
	 * @param content
	 */
	@SuppressWarnings("unused")
	public void sendEmailList(List<String> toList,String subject,String content) {
		SendMessageThread message = new SendMessageThread(toList,subject,content);
		(new Thread(message)).start();
	}
	
	/**
	 * 异步发送邮件内部类
	 *
	 */
	class SendMessageThread extends Thread {
		List<String> toList;
		String subject;
		String content;

		public SendMessageThread(List<String> toList, String subject,String content) {
			this.toList = toList;
			this.subject = subject;
			this.content = content;
		}

		String smsmsg = "";
		public void run() {
			synchronized (smsmsg) {
				for (String to: toList) {
					sendEmail( to, subject, content);
				}
			}
		}
	}
	
	
	/**
	 * 邀请用户进行激活的提醒
	 * @param toUser
	 * @param url 激活的URL
	 */
	public void sendEmailToActivate(String toUser,String userName,String url){
		String subject = "请激活您的开薪工资账户";
		String content = String.format(contentActivate, userName,url,url);
		sendEmail( toUser, subject, content);
	}
	
	
	/**
	 * 账户激活成功提醒
	 * @param toUser
	 * @param url 登录URL
	 */
	public void sendEmailToActivateSuccess(String toUser,String url){
		String subject = "开薪工资账户激活成功";
		String content = String.format(contentActivateSuccess, url,url);
		sendEmail( toUser, subject, content);
	}
	
	
	/**
	 * 账户冻结提醒
	 * @param toUser
	 */
	public void sendEmailToFreeze(String toUser){
		String subject = "您的开薪工资账户已被冻结";
		String content = contentFreeze;
		sendEmail( toUser, subject, content);
	}
	
	/**
	 * 修改登录密码成功后提醒
	 * @param toUser
	 * @param customPhone 客服电话
	 */
	public void sendEmailToModifyLoginPass(String toUser,String date){
		String subject = "您的账户修改登录密码成功";
		String content = String.format(contentModifyLoginPass,date, customPhone);
		sendEmail( toUser, subject, content);
	}
	/**
	 * 修改支付密码成功后提醒
	 * @param toUser
	 * @param customPhone 客服电话
	 */
	public void sendEmailToModifyPayPass(String toUser,String date){
		String subject = "您的账户修改支付密码成功";
		String content = String.format(contentModifyPayPass, date,customPhone);
		sendEmail( toUser, subject, content);
	}
	/**
	 * 账户重置成功后提醒
	 * 用户账户丢失后，用户申请重置。重置成功后发送提醒
	 * @param toUser
	 * @param url
	 */
	public void sendEmailToResetUser(String toUser,String url){
		String subject = "您的账户重置成功";
		String content = String.format(contentReset,url,url);
		sendEmail( toUser, subject, content);
		
	}
	
	/**
	 * 用户账户资料修改提醒--修改绑定手机号码
	 * @param toUser
	 * @param oldPhone
	 * @param newPhone
	 */
	public void sendEmailToModifyPhone(String toUser,String oldPhone,String newPhone){
		String subject = "您的用户资料修改成功";
		String content = String.format(contentModifyPhone,oldPhone,newPhone);
		sendEmail( toUser, subject, content);
	}
	/**
	 * 用户账户资料修改提醒--修改绑定邮箱
	 * @param toUser
	 * @param oldEmail
	 * @param newEmail
	 */
	public void sendEmailToModifyEmail(String toUser,String oldEmail,String newEmail){
		String subject = "您的用户资料修改成功";
		String content = String.format(contentModifyEmail,oldEmail,newEmail);
		sendEmail( toUser, subject, content);
	}
	/**
	 * 用户账户资料修改提醒--修改绑定银行卡
	 * @param toUser
	 * @param oldBank
	 * @param newBank
	 */
	public void sendEmailToModifyBank(String toUser,String oldBank,String newBank){
		String subject = "您的用户资料修改成功";
		String content = String.format(contentModifyBank,oldBank,newBank);
		sendEmail( toUser, subject, content);
	}
	/**
	 * 用户账户资料修改提醒--修改绑定身份id
	 * @param toUser
	 * @param oldCard
	 * @param newCard
	 */
	public void sendEmailToModifyCard(String toUser,String oldCard,String newCard){
		String subject = "您的用户资料修改成功";
		String content = String.format(contentModifyCard,oldCard,newCard);
		sendEmail( toUser, subject, content);
	}
	
	
	/**
	 * 请确认您的开薪工资账户信息
	 * ［开薪工资］亲爱的＃＃                 请确认您的开薪工资账户信息       如果点击无效，请复制下方网页地址到浏览器地址栏中打开：https://salary.trusdom.com/misc/html/index.html
	 * @param toUser
	 * @param user
	 * @param url
	 */
	public void sendEmailToConfirm(String toUser,String user,String url){
		String subject = "请确认您的开薪工资账户信息";
		String content = String.format(contentConfirm,user,url,url);
		sendEmail( toUser, subject, content);
	}
	/**
	 * 用户信息修改成功提醒
	 * [开薪工资］尊敬的用户，您的开薪工资账户信息已修改成功。请登录https://salary.trusdom.com/misc/html/index.html查看您的开薪工资账户
	 * @param toUser
	 * @param user
	 * @return
	 */
	public void sendEmailToRemind(String toUser,String url){
		String subject = "开薪工资账户信息修改成功";
		String content = String.format(contentRemind,url,url);
		sendEmail( toUser, subject, content);
		
	}

	
	/**
	 * 异步发送邮件内部类
	 *
	 */
	class SendEmailThread extends Thread {
		String to;
		String subject;
		String content;

		public SendEmailThread(String to, String subject,String content) {
			this.to = to;
			this.subject = subject;
			this.content = content;
		}

		String smsmsg = "";
		public void run() {
			synchronized (smsmsg) {
				try {
					 // 添加html形式的邮件正文
			        BodyPart part1 = new MimeBodyPart();
			        part1.setHeader("Content-Type", "text/html;charset=UTF-8");
			        part1.setHeader("Content-Transfer-Encoding", "base64");
			        part1.setContent(content, "text/html;charset=UTF-8");
			        Multipart multipart = new MimeMultipart("alternative");
			        multipart.addBodyPart(part1);
			        
			        MimeMessage message = new MimeMessage(mailSession);
			        message.setContent(multipart);

			        // 发信人，用正确邮件地址替代  netpay@trusdom.com
			        message.setFrom(new InternetAddress("zhanlong1988@126.com", "开薪工资", "UTF-8"));
			        // 收件人地址，用正确邮件地址替代
			        message.addRecipient(RecipientType.TO, new InternetAddress(to));
			        // 邮件主题
			        message.setSubject(subject, "UTF-8");
			        LOGGER.info("send email to " + to + " subject " + subject);
			        // 连接sendcloud服务器，发送邮件
			        transport = mailSession.getTransport();
			        transport.connect();
			        transport.sendMessage(message, message.getRecipients(RecipientType.TO));
			        transport.close();
				} catch (Exception e) {
					LOGGER.error("send email to " + to + " subject " + subject,e);
				}
			}
		}
	}
	
	public static void main(String[] args){
		List<String> emailList= new ArrayList<String>();
		             emailList.add("340417593@qq.com");
		MailThreadService.getInstance().sendEmailList(emailList, "开发人员测试", "我自己能发送邮件了");
	}
}
